package com.clwl.supervise.superviseapp.util.file;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.clwl.supervise.superviseapp.mapper.base.SysConfigMapper;
import io.minio.*;
import okhttp3.HttpUrl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.UUID;

/**
 * 上传文件
 */
@Component
public class FileUploadUtil {

    private static Logger logger = LoggerFactory.getLogger(FileUploadUtil.class);


    //获取开发配置的临时赋值
    public static final String fileUploadActive;

    public static final String devUploadBucket;

    private static final String devUploadPath;

    public static final String devViewPath;

    private static final String devUploadAccount;

    private static final String devUploadPassword;

    /**
     * 上传用的 生产查看的地址内网的
     */
    private static final MinioClient minioClient;


    /**
     * 查看用的 生产查看的地址外网的和上传地址不同
     */
    public static final MinioClient minioShowClient;


    //去数据库获取配置信息的keu
    private static final String minioUploadUrlKey = "SYS_CONFIG_MINIO_UPLOAD_URL";
    private static final String minioViewUrlKey = "SYS_CONFIG_MINIO_VIEW_URL";

    private static final String minioAccountKey = "SYS_CONFIG_MINIO_ACCOUNT";

    private static final String minioPasswordKey = "SYS_CONFIG_MINIO_PASSWORD";

    public static final String minioBucketKey = "SYS_CONFIG_MINIO_BUCKET";

    static {
        FileUploadProperties fileUploadProperties = SpringUtil.getBean(FileUploadProperties.class);
        fileUploadActive = fileUploadProperties.getFileUploadActive();
        devUploadAccount = fileUploadProperties.getDevUploadAccount();
        devUploadPassword = fileUploadProperties.getDevUploadPassword();
        devUploadBucket = fileUploadProperties.getDevUploadBucket();
        devUploadPath = StringUtils.equals(fileUploadActive, "dev") ? fileUploadProperties.getDevUploadPath() : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioUploadUrlKey).getParamValue(), fileUploadProperties.getDevUploadPath());
        devViewPath = StringUtils.equals(fileUploadActive, "dev") ? fileUploadProperties.getDevViewPath() : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioViewUrlKey).getParamValue(), fileUploadProperties.getDevViewPath());
        String account = StringUtils.equals(fileUploadActive, "dev") ? devUploadAccount : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioAccountKey).getParamValue(), devUploadAccount);
        String password = StringUtils.equals(fileUploadActive, "dev") ? devUploadPassword : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioPasswordKey).getParamValue(), devUploadPassword);
        String uploadBucket = StringUtils.equals(fileUploadActive, "dev") ? devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioBucketKey).getParamValue(), devUploadBucket);
        logger.info("minio服务器上传地址:{}", devUploadPath);
        logger.info("minio服务器查看地址:{}", devViewPath);
        logger.info("文件上传配置:{}", fileUploadActive);
        logger.info("文件上传桶:{}", uploadBucket);
        logger.info("文件上传账号:{}", account);
        logger.info("文件上传密码:{}", password);
        minioClient = MinioClient.builder().endpoint(devUploadPath).credentials(account, password).build();
        HttpUrl showUrl = HttpUrl.get(devViewPath);
        logger.info("showUrl.encodedPath():{}", showUrl.encodedPath());
        minioShowClient = MinioClient.builder().endpoint(devViewPath.replace(showUrl.encodedPath(), "")).credentials(account, password).build();
        try {
            minioShowClient.ignoreCertCheck();
        } catch (KeyManagementException e) {
            logger.error("忽略证书检查失败KeyManagementException:{}", e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            logger.error("忽略证书检查失败NoSuchAlgorithmException:{}", e.getMessage());
        }
    }


    /**
     * 上传图片
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static FileResultEntity uploadImage(MultipartFile file, String pathPrefix) throws Exception {
        FileResultEntity fileResultEntity = new FileResultEntity();
        //String uploadPath = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? devUploadPath : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey("SYS_CONFIG_ROOT_PATH").getParamValue(), "/home/files/clwlkb/");
        String uploadBucket = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? FileUploadUtil.devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(FileUploadUtil.minioBucketKey).getParamValue(), FileUploadUtil.devUploadBucket);

        //如果不存在，制作桶。
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(uploadBucket).build());
        if (!found) {
            //创建桶
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(uploadBucket).build());
        }
        byte[] bytes = file.getBytes();
        String fileBase64 = Base64.getEncoder().encodeToString(bytes);
        fileResultEntity.setFilePicture(fileBase64);
        //minio上传文件流
        String fileName = file.getOriginalFilename().replaceAll(" ", "").replaceAll(";", "");
        String filePath = pathPrefix + fileName;
        logger.info("文件地址:{}" + filePath);
        InputStream inputStream = file.getInputStream();
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(uploadBucket).object(filePath).stream(
                            inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
        }

        ///File saveFile = new File(filePath);
        //File saveThFile = new File(filePath);
        //logger.info("文件存储地址:{}",saveFile);
        //file.transferTo(saveFile);
        //BufferedImage bufferedImage = Thumbnailator.createThumbnail(saveFile, 200, 200);
        //ImageIO.write(bufferedImage, file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1), saveThFile);
        fileResultEntity.setFileName(fileName);
        fileResultEntity.setThFileName(fileName);
        fileResultEntity.setFilePath(uploadBucket + "/" + filePath);
        fileResultEntity.setFileThPath(uploadBucket + "/" + filePath);
        return fileResultEntity;
    }

    /**
     * 上传文件
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static FileResultEntity uploadFile(MultipartFile file, String pathPrefix) throws Exception {
        FileResultEntity fileResultEntity = new FileResultEntity();
        String uploadBucket = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? FileUploadUtil.devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(FileUploadUtil.minioBucketKey).getParamValue(), FileUploadUtil.devUploadBucket);

        //如果不存在，制作桶。
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(uploadBucket).build());
        if (!found) {
            //创建桶
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(uploadBucket).build());
        }

        //minio上传文件流
        String fileName = file.getOriginalFilename().replaceAll(" ", "").replaceAll(";", "");
        String filePath = pathPrefix + fileName;
        logger.info("文件地址:{}" + filePath);
        InputStream inputStream = file.getInputStream();
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(uploadBucket).object(filePath).stream(
                            inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
        }
      /*  String uploadPath = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? devUploadPath : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey("SYS_CONFIG_ROOT_PATH").getParamValue(), "/home/files/clwlkb/");
        System.out.println("uploadPath:"+uploadPath);
        System.out.println(file);
        File filePath = new File(uploadPath);
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        String fileName =  file.getOriginalFilename().replaceAll(" ", "").replaceAll(";", "");
        String fileSavePath = uploadPath + File.separator + fileName;

        logger.info("文件存储地址:{}",fileSavePath);
        File saveFile = new File(fileSavePath);
        file.transferTo(saveFile);*/
        fileResultEntity.setFileName(fileName);
        fileResultEntity.setFilePath(uploadBucket + "/" + filePath);
        return fileResultEntity;
    }

    /**
     * 删除指定文件
     *
     * @param filePath
     */
    public static void deleteFile(String filePath) throws Exception {
       /* String uploadPath = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? devUploadPath : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey("SYS_CONFIG_ROOT_PATH").getParamValue(), "/home/files/clwlkb/");
        File filePath = new File(uploadPath + File.separator);
         filePath.delete();
         */
        String uploadBucket = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? FileUploadUtil.devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(FileUploadUtil.minioBucketKey).getParamValue(), FileUploadUtil.devUploadBucket);

        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(uploadBucket).build());
        if (!found) {
            //如果桶不存在则不删除
            return;
        }
        //minio删除文件
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(uploadBucket).object(filePath.replace(uploadBucket + "/", "")).build());

    }

    /**
     * 通过base64信息将SVG上传文件
     *
     * @param svgContent
     * @return
     */
    public static FileResultEntity uploadSVGBase64Image(String svgContent, String pathPrefix) throws Exception {

       /* String uploadPath = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? devUploadPath : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey("SYS_CONFIG_ROOT_PATH").getParamValue(), "/home/files/clwlkb/");
        // 将编码后的字符串保存到文件
        String fileName =  UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis() + ".png";
        String filePath = uploadPath + File.separator + "sign" +  File.separator ;
        String fileSavePath = filePath + fileName ;
        File filePathExists = new File(filePath);
        if (!filePathExists.exists()) {
            filePathExists.mkdirs();
        }
        // 将Base64内容解码为字节数组
        byte[] svgBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(svgContent.split("base64,")[1]);

        // 将字节数组读取为InputStream
        InputStream svgStream = new ByteArrayInputStream(svgBytes);

        // 使用Batik将SVG渲染为BufferedImage
        PNGTranscoder transcoder = new PNGTranscoder();
        TranscoderInput transcoderInput = new TranscoderInput(svgStream);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        TranscoderOutput transcoderOutput = new TranscoderOutput(outputStream);
        transcoder.transcode(transcoderInput, transcoderOutput);

        // 将BufferedImage保存为PNG文件
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(outputStream.toByteArray()));
        logger.info("文件存储地址:{}",fileSavePath);
        File output = new File(fileSavePath); // 这里替换为你想保存的文件路径
        ImageIO.write(image, "png", output);

        System.out.println("图片保存成功！");*/
        String uploadBucket = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? FileUploadUtil.devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(FileUploadUtil.minioBucketKey).getParamValue(), FileUploadUtil.devUploadBucket);

        //如果不存在，制作桶。
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(uploadBucket).build());
        if (!found) {
            //创建桶
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(uploadBucket).build());
        }

        //minio上传文件流
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis() + ".png";
        String filePath = pathPrefix + fileName;
        logger.info("svg内容:{}", svgContent);
        logger.info("文件地址:{}", filePath);
        if (StringUtils.isEmpty(svgContent)) {
            FileResultEntity fileResultEntity = new FileResultEntity();
            return fileResultEntity;
        }
        // 将Base64内容解码为字节数组
        byte[] svgBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(svgContent.split("base64,")[1]);
        // 将字节数组读取为InputStream
        InputStream svgStream = new ByteArrayInputStream(svgBytes);
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(uploadBucket).object(filePath).stream(
                            svgStream, -1, 10485760)
                    .contentType("image/png")
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            svgStream.close();
        }

        FileResultEntity fileResultEntity = new FileResultEntity();
        fileResultEntity.setFileName(uploadBucket + "/" + filePath);
        fileResultEntity.setFilePath(uploadBucket + "/" + filePath);
        return fileResultEntity;
    }

    /**
     * 通过base64信息将SVG上传文件
     *
     * @return
     */
    public static FileResultEntity uploadImageBase64Image(String base64Image, String pathPrefix) throws Exception {
     /*   String uploadPath = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? devUploadPath : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey("SYS_CONFIG_ROOT_PATH").getParamValue(), "/home/files/clwlkb/");
        // 将编码后的字符串保存到文件
        String fileName =  UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis() + ".png";
        String filePath = uploadPath + File.separator + "sign" +  File.separator ;
        String fileSavePath = filePath + fileName ;
        File filePathExists = new File(filePath);
        if (!filePathExists.exists()) {
            filePathExists.mkdirs();
        }
        // 将Base64内容解码为字节数组
        byte[] decodedBytes = Base64.getDecoder().decode(base64Image.substring(base64Image.indexOf(",") + 1));

        // 保存为本地图片文件
        try (FileOutputStream outputStream = new FileOutputStream(fileSavePath)) {
            outputStream.write(decodedBytes);

        } catch (IOException e) {
            e.printStackTrace();
        }*/
        String uploadBucket = StringUtils.equals(FileUploadUtil.fileUploadActive, "dev") ? FileUploadUtil.devUploadBucket : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(FileUploadUtil.minioBucketKey).getParamValue(), FileUploadUtil.devUploadBucket);

        //如果不存在，制作桶。
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(uploadBucket).build());
        if (!found) {
            //创建桶
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(uploadBucket).build());
        }

        //minio上传文件流
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis() + ".png";
        String filePath = pathPrefix + fileName;
        logger.info("文件地址:{}" + filePath);
        // 将Base64内容解码为字节数组
        byte[] decodedBytes = Base64.getDecoder().decode(base64Image.substring(base64Image.indexOf(",") + 1));
        // 将字节数组读取为InputStream
        InputStream svgStream = new ByteArrayInputStream(decodedBytes);
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(uploadBucket).object(filePath).stream(
                            svgStream, -1, 10485760)
                    .contentType("image/png")
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            svgStream.close();
        }
        FileResultEntity fileResultEntity = new FileResultEntity();
        fileResultEntity.setFileName(fileName);
        fileResultEntity.setFilePath(uploadBucket + "/" + filePath);
        return fileResultEntity;
    }


    /**
     * 上传图片识别的时候缓存用的图片
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static FileResultEntity uploadTempImage(MultipartFile file) throws Exception {
        FileResultEntity fileResultEntity = new FileResultEntity();
        File saveFilePath = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath());
        File saveFile = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath() + saveFilePath.separator + file.getOriginalFilename());
        if (!saveFilePath.exists()) {
            saveFilePath.mkdirs();
        }
        logger.info("文件存储地址:{}", saveFilePath.getAbsolutePath());
        file.transferTo(saveFile);
        fileResultEntity.setFileName(file.getOriginalFilename());
        fileResultEntity.setFilePath(Thread.currentThread().getContextClassLoader().getResource("").getPath() + file.getOriginalFilename());
        return fileResultEntity;
    }

    /**
     * 删除图片识别的时候缓存用的图片
     *
     * @return
     * @throws IOException
     */
    public static void deleteTempImage(String tempFilePath) {
        try {
            logger.info("删除文件,tempFilePath:{}", tempFilePath);
            File filePath = new File(tempFilePath);
            filePath.delete();
        } catch (Exception e) {
            logger.error("删除缓存文件失败:{}", e.getMessage());
        }
    }

    public static String getViewUrl() {
        FileUploadProperties fileUploadProperties = SpringUtil.getBean(FileUploadProperties.class);
        return StringUtils.equals(fileUploadActive, "dev") ? fileUploadProperties.getDevViewPath() : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioViewUrlKey).getParamValue(), fileUploadProperties.getDevViewPath());
    }

    public static String getMinioBucket() {
        FileUploadProperties fileUploadProperties = SpringUtil.getBean(FileUploadProperties.class);
        return StringUtils.equals(fileUploadActive, "dev") ? fileUploadProperties.getDevUploadBucket() : StrUtil.blankToDefault(SpringUtil.getBean(SysConfigMapper.class).queryByKey(minioBucketKey).getParamValue(), fileUploadProperties.getDevUploadBucket());
    }
}
